package streamforce.crypto.cloud.subscriber;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import streamforce.Stat;
import streamforce.crypto.KPAbe;
import streamforce.crypto.cloud.EPCloud;
import streamforce.crypto.cloud.EPCloudServer;
import streamforce.crypto.cloud.TimeTuple;
import streamforce.crypto.cloud.Tuple;
import streamforce.crypto.event.Ciphertext;
import streamforce.crypto.event.StockEvent;
import streamforce.crypto.event.StockEventJoin;
import streamforce.crypto.event.TransformedCTEventJoin;
import streamforce.crypto.policies.Policy;

/**
 * Had the join result. Now transform the result 
 */
public class CloudJoinVolumeStage2 extends Policy{
	private final Log log = LogFactory.getLog(CloudJoinVolumeStage2.class);
	int userId1, userId2; //user ID for join
	Stat statTuple; 
	public CloudJoinVolumeStage2(int userId1, int userId2, KPAbe ch){
		super(ch); 
		this.userId1 = userId1;
		this.userId2 = userId2;
		this.statTuple = new Stat("nTuples"); 
	}
	//price here is encrypted with ws=1
	public  void update(int ts1, int hour1, int sid1, int ts2, int hour2, int sid2, Ciphertext price1, Ciphertext price2,
			Ciphertext volume) {
		TimeTuple tt = EPCloudServer.tupleTime.get(new Tuple(sid1, ts1)); 
		if (tt.getCount()==0)
			this.statTuple.update(); 			
		tt.increaseCount();
		
		tt = EPCloudServer.tupleTime.get(new Tuple(sid2, ts2)); 
		if (tt.getCount()==0)
			this.statTuple.update(); 			
		tt.increaseCount(); 	
		byte[][] originals, transforms; 
		
		byte[] ciphertext = price1.getCipher();
		long start = System.currentTimeMillis();
		/*byte[] oct = this.cryptoHandler.extractOriginalCipher(sid1, ciphertext);
		byte[] tct = this.cryptoHandler.transform_simple(ciphertext, sid1,this.userId1);
		originals = new byte[3][oct.length];
		transforms = new byte[3][tct.length];
		originals[0] = oct; 
		transforms[0] = tct;*/
		
		//volume1
		byte[] oct = this.cryptoHandler.extractOriginalCipher(sid2, price2.getCipher());
		byte[] tct = this.cryptoHandler.transform_simple(price2.getCipher(), sid2, this.userId2);
		originals = new byte[2][oct.length];
		transforms = new byte[2][tct.length];
		originals[0] = oct;
		transforms[0] = tct;
		
		//volume2
		oct = this.cryptoHandler.extractOriginalCipher(sid1, volume.getCipher());
		tct = this.cryptoHandler.transform_simple(volume.getCipher(), sid1, this.userId1);
		originals[1] = oct;
		transforms[1] = tct;
		
		long end = System.currentTimeMillis();
		log.debug("transformation time = " + (end - start));

			// then construct and send another event
		TransformedCTEventJoin cte = new TransformedCTEventJoin(
				this.userId1, this.userId2, ts1, hour1, sid1, ts2, hour2, sid2, originals,
				transforms);
		EPCloud.getEPServiceProvider().getEPRuntime().sendEvent(cte);								
	}		
}
